package org.yoki.edu.netsdk;

import java.io.File;
import java.lang.reflect.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.sun.jna.Memory;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import org.yoki.edu.lib.NetSDKLib;
import org.yoki.edu.lib.NetSDKTools;

class MenuItemEx
{
	Object instance;
	String strItemName;
	String strItemFunc;

	public  MenuItemEx(Object instance , String strItemName , String strItemFunc )
	{
		this.instance = instance;
		this.strItemName = strItemName;
		this.strItemFunc = strItemFunc;
	}
}

class MenuEx
{
	List<MenuItemEx> menuItems = new ArrayList<MenuItemEx>();
	String strPrintFormat = "%2d\t%-20s\n";
	
	public void AddItem(MenuItemEx item)
	{
		menuItems.add(item);
	}
	
	public void Run()
	{
		Scanner sc = new Scanner(System.in);
		while(true)
		{
			try 
			{	
				MenuItemEx item = null;
				for(int i=0 ; i<menuItems.size() ; i++)
				{
					item = menuItems.get(i);
					System.out.printf(strPrintFormat , i+1 , item.strItemName);
				}
				System.out.printf(strPrintFormat, 0 , "Exit App");
				
				String strUserInput = new String();
				
				if (sc.hasNext())
				{
					strUserInput = sc.next();
				}
				
				int nUserInput = 0;
				try
				{
					nUserInput  = Integer.parseInt(strUserInput);
				}
				catch(NumberFormatException ex)
				{
					nUserInput = -1;
				}
				
				// 等于0退出
				if( 0 == nUserInput )
				{
					break;
				}
				
				// 如果不在范围内则报错
				if ((nUserInput < 0) || 
					(nUserInput > menuItems.size()))
				{
					System.out.println("Input Error");
					continue;
				}

				item =  menuItems.get(nUserInput-1);
				if( item  != null)
				{
					Class<?> testClass = item.instance.getClass();
					Method method = testClass.getMethod(item.strItemFunc);
					method.invoke(item.instance);
				}
				else
				{
					System.out.println("Input Error");
				}
		
			} 
			catch (Exception e) 
			{
				System.out.println(e);
				e.printStackTrace();
			}
		}
	}
}

public class JNADemo {
	
	static NetSDKLib NetSdk 	= NetSDKLib.COMMON_INSTANCE;
	static NetSDKLib ConfigSdk 	= NetSDKLib.CONFIG_INSTANCE;
	
	private NetSDKLib.NET_DEVICEINFO m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO();
	private NativeLong m_hLoginHandle = new NativeLong(0);   //登陆句柄
	private NativeLong m_hAttachHandle = new NativeLong(0);
	private NativeLong m_hAttachParkHandle = new NativeLong(0);
	private NativeLong m_hFindHandle = new NativeLong(0);
	private NativeLong m_lAttachHandle = new NativeLong(0);
	private NativeLong m_TransComChannel = new NativeLong(0);

	String m_strIp 			= "172.23.1.32";
	int    m_nPort 			= 37777;
	String m_strUser 		= "admin";
	String m_strPassword 	= "admin";
	
	//设备断线回调: 通过 CLIENT_Init 设置该回调函数，当设备出现断线时，SDK会调用该函数
	public class fDisConnectCB implements NetSDKLib.fDisConnect{
		public void invoke(NativeLong lLoginID, String pchDVRIP, int nDVRPort, NativeLong dwUser){
			System.out.printf("Device[%s] Port[%d] Disconnect!\n" , pchDVRIP , nDVRPort);
		}	
    }
	
	//网络连接恢复，设备重连成功回调
	// 通过 CLIENT_SetAutoReconnect 设置该回调函数，当已断线的设备重连成功时，SDK会调用该函数
	public class HaveReConnect implements NetSDKLib.fHaveReConnect {
		public void invoke(NativeLong m_hLoginHandle, String pchDVRIP, int nDVRPort, NativeLong dwUser) {
			System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);
		}
	}

	private fDisConnectCB  	m_DisConnectCB   = new fDisConnectCB();
	private HaveReConnect haveReConnect = new HaveReConnect(); 
	
	public void EndTest()
	{
		System.out.println("End Test");
		if( m_hLoginHandle.longValue() != 0)
		{
			NetSdk.CLIENT_Logout(m_hLoginHandle);
		}
		System.out.println("See You...");
		
		NetSdk.CLIENT_Cleanup();
		System.exit(0);
	}

	public void InitTest()
	{
		//初始化SDK库
		NetSdk.CLIENT_Init(m_DisConnectCB, new NativeLong(0));
    	
		// 设置断线重连回调接口，设置过断线重连成功回调函数后，当设备出现断线情况，SDK内部会自动进行重连操作
		// 此操作为可选操作，但建议用户进行设置
		NetSdk.CLIENT_SetAutoReconnect(haveReConnect, new NativeLong(0));
		
		//设置登录超时时间和尝试次数，可选
		int waitTime = 5000; //登录请求响应超时时间设置为5S
		int tryTimes = 3;    //登录时尝试建立链接3次
		NetSdk.CLIENT_SetConnectTime(waitTime, tryTimes);
		
		// 设置更多网络参数，NET_PARAM的nWaittime，nConnectTryNum成员与CLIENT_SetConnectTime 
		// 接口设置的登录设备超时时间和尝试次数意义相同,可选
		NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
		netParam.nConnectTime = 10000; //登录时尝试建立链接的超时时间
		NetSdk.CLIENT_SetNetworkParam(netParam);	
		
    	// 向设备登入
    	int nSpecCap = 0;
    	Pointer pCapParam = null;
    	int nError[] = {0};
    	m_hLoginHandle = NetSdk.CLIENT_LoginEx(m_strIp, (short)m_nPort, m_strUser , 
				m_strPassword ,nSpecCap,pCapParam, m_stDeviceInfo,nError);
		
		if(m_hLoginHandle.longValue() != 0)
		{
    		System.out.printf("Login Device[%s] Port[%d]Success!\n" , m_strIp , m_nPort);
    	}
    	else
    	{	
    		System.out.printf("Login Device[%s] Port[%d]Fail.Last Error[%x]\n" , m_strIp , m_nPort , NetSdk.CLIENT_GetLastError());
    		EndTest();
    	}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
    
    ////交通流量查询
	public void findTrafficFlowState() {
		// 设置查询条件
		NetSDKLib.FIND_RECORD_TRAFFICFLOW_CONDITION flowCondition = new NetSDKLib.FIND_RECORD_TRAFFICFLOW_CONDITION();
		flowCondition.bStatisticsTime = 1;  //查询是否为统计时间
		flowCondition.bStartTime = 1; // 使能
		flowCondition.bEndTime = 1; // 使能
		flowCondition.stStartTime.dwYear = 2017;
		flowCondition.stStartTime.dwMonth = 5;
		flowCondition.stStartTime.dwDay = 3;
		flowCondition.stStartTime.dwHour = 1;
		flowCondition.stStartTime.dwMinute = 0;
		
	    flowCondition.stEndTime.dwYear = 2017; 
	    flowCondition.stEndTime.dwMonth = 5;		
	    flowCondition.stEndTime.dwDay = 3;
	    flowCondition.stEndTime.dwHour = 2;
		
		// CLIENT_FindRecord 入参
		NetSDKLib.NET_IN_FIND_RECORD_PARAM stuFindInParam = new NetSDKLib.NET_IN_FIND_RECORD_PARAM();
		stuFindInParam.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_TRAFFICFLOW_STATE; 
		stuFindInParam.pQueryCondition = flowCondition.getPointer();
		
		// CLIENT_FindRecord 出参
		NetSDKLib.NET_OUT_FIND_RECORD_PARAM stuFindOutParam = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM();
		
		flowCondition.write(); 
		boolean bRet = NetSdk.CLIENT_FindRecord(m_hLoginHandle, stuFindInParam, stuFindOutParam, 3000);
		flowCondition.read();		
		if(!bRet) {
			System.err.println("Can Not Find This Record" + Integer.toHexString(NetSdk.CLIENT_GetLastError()));
			return;
		}
		
		int count = 0;  //循环的次数
		int nFindCount = 0;	///查询到的总数初始化
		int nRecordCount = 10;  // 每次查询的个数
		NetSDKLib.NET_RECORD_TRAFFIC_FLOW_STATE[] pstRecord = new NetSDKLib.NET_RECORD_TRAFFIC_FLOW_STATE[nRecordCount];
		for(int i=0; i<nRecordCount; i++) {
			pstRecord[i] = new NetSDKLib.NET_RECORD_TRAFFIC_FLOW_STATE();
		}
		
		///CLIENT_FindNextRecord入参
		NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM stuFindNextInParam = new NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM();
		stuFindNextInParam.lFindeHandle = stuFindOutParam.lFindeHandle;
		stuFindNextInParam.nFileCount = nRecordCount;  //想查询的记录条数
		
		///CLIENT_FindNextRecord出参
		NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM stuFindNextOutParam = new NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM();
		stuFindNextOutParam.nMaxRecordNum = nRecordCount;
		stuFindNextOutParam.pRecordList = new Memory(pstRecord[0].dwSize * nRecordCount);
		stuFindNextOutParam.pRecordList.clear(pstRecord[0].dwSize * nRecordCount);	
	
		NetSDKTools.SetStructArrToPointerData(pstRecord, stuFindNextOutParam.pRecordList);	//将数组内存拷贝给Pointer指针
		
		while(true) {  //循环查询			
			if(NetSdk.CLIENT_FindNextRecord(stuFindNextInParam, stuFindNextOutParam, 5000) ) {
				NetSDKTools.GetPointerDataToStructArr(stuFindNextOutParam.pRecordList, pstRecord);

				for(int i=0; i < stuFindNextOutParam.nRetRecordNum; i++) {
					nFindCount = i + count * nRecordCount;				
					
					System.out.println("[" + nFindCount + "]记录编号:" + pstRecord[i].nRecordNum);
					System.out.println("[" + nFindCount + "]通道号:" + pstRecord[i].nChannel);
					System.out.println("[" + nFindCount + "]车道号:" + pstRecord[i].nLane);
					System.out.println("[" + nFindCount + "]通过车辆总数:" + pstRecord[i].nVehicles);
				}							
				
				if (stuFindNextOutParam.nRetRecordNum < nRecordCount)
				{
					break;
				} else {
					count ++;
				}
			} else {
				break;
			}
		}
		System.out.println("查询到的总数 : " + (nFindCount + 1));
		NetSdk.CLIENT_FindRecordClose(new NativeLong(stuFindOutParam.lFindeHandle));
	}
    
	// 开始录像
	public void recordMode() {
		String szCommand = NetSDKLib.CFG_CMD_RECORDMODE;
		
		NetSDKLib.AV_CFG_RecordMode[] recordModes = new NetSDKLib.AV_CFG_RecordMode[m_stDeviceInfo.byChanNum];  // m_stDeviceInfo.byChanNum为设备通道数
		for (int i = 0; i < recordModes.length; ++i) {
			recordModes[i] = new NetSDKLib.AV_CFG_RecordMode();
		}
		
		int retCount = NetSDKTools.GetDevConfig(m_hLoginHandle, -1, szCommand, recordModes);
		for (int i = 0; i < retCount; i++) {
			System.out.println("i " + i + "录像模式:" + recordModes[i].nMode + "\n" + " 辅码流录像模式:" + recordModes[i].nModeExtra1);
		}
		
//		for(int i=0; i<recordModes.length; i++) {
//		    recordModes[i].nMode = 1;
//			recordModes[i].nModeExtra1 = 1;
//		}
		
	    recordModes[0].nMode = 1;
		recordModes[0].nModeExtra1 = 2;
		
	    recordModes[1].nMode = 1;
		recordModes[1].nModeExtra1 = 2;

		boolean bRet = NetSDKTools.SetDevConfigArr(m_hLoginHandle, -1, szCommand, recordModes);
		if(bRet) {
			for (int i = 0; i < retCount; i++) {
				System.out.println("i = " + i + "\n" + "录像模式:" + recordModes[i].nMode + "\n" + " 辅码流录像模式:" + recordModes[i].nModeExtra1);
			}
		}
	}
	
	
	
	
	// 查找录像文件帧信息
	public void findFrameInfo() {
		// 1、先查询时间段内的文件信息
		NetSDKLib.NET_TIME stTimeStart = new NetSDKLib.NET_TIME();
		stTimeStart.dwYear = 2017;
		stTimeStart.dwMonth = 4;
		stTimeStart.dwDay = 1;
		stTimeStart.dwHour =0;
		stTimeStart.dwMinute = 0;
		stTimeStart.dwSecond = 0;
		
		NetSDKLib.NET_TIME stTimeEnd = new NetSDKLib.NET_TIME();
		stTimeEnd.dwYear = 2017;
		stTimeEnd.dwMonth = 4;
		stTimeEnd.dwDay = 1;
		stTimeEnd.dwHour = 24;
		stTimeEnd.dwMinute = 0;
		stTimeEnd.dwSecond = 0;
		
		//**************按时间查找视频文件**************
		int nFileCount = 50; //每次查询的最大文件个数
		NetSDKLib.NET_RECORDFILE_INFO[] numberFile = (NetSDKLib.NET_RECORDFILE_INFO[])new NetSDKLib.NET_RECORDFILE_INFO().toArray(nFileCount);
		int maxlen = nFileCount * numberFile[0].size();

		IntByReference outFileCoutReference = new IntByReference(0);
		
		boolean cRet = NetSdk.CLIENT_QueryRecordFile(m_hLoginHandle, 0, 0, stTimeStart, stTimeEnd, null, numberFile, maxlen, outFileCoutReference, 5000, false);
		
		if(cRet) {
			System.out.println("QueryRecordFile  Succeed! \n" + "查询到的视频个数：" + outFileCoutReference.getValue() 
							   + "\n" + "码流类型：" + numberFile[0].bRecType);	
			for(int i=0; i<outFileCoutReference.getValue(); i++) {
				System.out.println("【" + i + "】：");
				System.out.println("开始时间：" + numberFile[i].starttime);
				System.out.println("结束时间：" + numberFile[i].endtime);
				System.out.println("通道号：" + numberFile[i].ch);
			}
			
		} else {
			System.err.println("QueryRecordFile  Failed!" + NetSdk.CLIENT_GetLastError());
		}
		
/*		
		// 2、利用上面查到的文件信息，获取查询句柄
		NetSDKLib.NET_IN_FIND_FRAMEINFO_PRAM inFindFrame = new NetSDKLib.NET_IN_FIND_FRAMEINFO_PRAM();
		inFindFrame.stuRecordInfo.ch = 0;    // 有视频的通道,对应打标签的视频时间
		inFindFrame.stuRecordInfo = numberFile[28];
		
		
		// 有视频的时间段，与上面的通道要对应
		inFindFrame.stuRecordInfo.starttime.dwYear = 2016;
		inFindFrame.stuRecordInfo.starttime.dwMonth = 11;
		inFindFrame.stuRecordInfo.starttime.dwDay = 16;
		inFindFrame.stuRecordInfo.starttime.dwHour = 23;
		inFindFrame.stuRecordInfo.starttime.dwMinute = 0;
		inFindFrame.stuRecordInfo.starttime.dwSecond = 0;
		
		inFindFrame.stuRecordInfo.endtime.dwYear = 2016;
		inFindFrame.stuRecordInfo.endtime.dwMonth = 11;
		inFindFrame.stuRecordInfo.endtime.dwDay = 16;
		inFindFrame.stuRecordInfo.endtime.dwHour = 23;
		inFindFrame.stuRecordInfo.endtime.dwMinute = 59;
		inFindFrame.stuRecordInfo.endtime.dwSecond = 0;
		
		NetSDKLib.NET_OUT_FIND_FRAMEINFO_PRAM outFindFrame = new NetSDKLib.NET_OUT_FIND_FRAMEINFO_PRAM();

		boolean bRet = NetSdk.CLIENT_FindFrameInfo(m_hLoginHandle, inFindFrame, outFindFrame, 5000);
		if(bRet){
			m_hFindHandle = outFindFrame.lFindHandle;
			System.out.println("FindFrameInfo Succeed!" + outFindFrame.lFindHandle);
		} else {
			System.err.println("FindFrameInfo Failed!" + NetSdk.CLIENT_GetLastError());
		}  */
	}
	
	// 获取标签信息（查找录像文件帧信息获取m_hFindHandle后，再用此功能）即通过标签查询录像
	public void getTags() {
		NetSDKLib.NET_IN_FILE_STREAM_GET_TAGS_INFO inFileGetTags = new NetSDKLib.NET_IN_FILE_STREAM_GET_TAGS_INFO();
		
		NetSDKLib.NET_OUT_FILE_STREAM_GET_TAGS_INFO outFielGetTags = new NetSDKLib.NET_OUT_FILE_STREAM_GET_TAGS_INFO();
		
		int nMaxNumber = 10;			
		NetSDKLib.NET_FILE_STREAM_TAG_INFO_EX[] pstuTagInfoArr =  new NetSDKLib.NET_FILE_STREAM_TAG_INFO_EX[nMaxNumber];
		for (int i = 0; i < pstuTagInfoArr.length; ++i) {
			pstuTagInfoArr[i] = new NetSDKLib.NET_FILE_STREAM_TAG_INFO_EX();
		}

		outFielGetTags.nMaxNumber = nMaxNumber;
		outFielGetTags.pstuTagInfo = new Memory(nMaxNumber * pstuTagInfoArr[0].size());
		outFielGetTags.pstuTagInfo.clear(nMaxNumber * pstuTagInfoArr[0].size());
		
		NetSDKTools.SetStructArrToPointerData(pstuTagInfoArr, outFielGetTags.pstuTagInfo);

		inFileGetTags.write();
		outFielGetTags.write();
		boolean bRet = NetSdk.CLIENT_FileStreamGetTags(m_hFindHandle, inFileGetTags, outFielGetTags, 5000);
		
		NetSDKTools.GetPointerDataToStructArr(outFielGetTags.pstuTagInfo, pstuTagInfoArr);
		
		inFileGetTags.read();
		outFielGetTags.read();
		if(bRet) {
			System.out.println("实际返回的标签信息个数 = " + outFielGetTags.nRetTagsCount);
			for(int i=0; i<outFielGetTags.nRetTagsCount; ++i) {
				System.out.println("【" + i + "】:" + "\n" + pstuTagInfoArr[i].stuTime + "\n" + 
									pstuTagInfoArr[i].nSequence + "\n" +
									new String(pstuTagInfoArr[i].szContext).trim() + "\n" +
									pstuTagInfoArr[i].emType + "\n" +
									new String(pstuTagInfoArr[i].szUserName).trim() + "\n" +
									new String(pstuTagInfoArr[i].szChannelName).trim());
			}
		} else {
			System.err.println("GetTags Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	
	// 设置标签信息（查找录像文件帧信息获取m_hFindHandle后，再用此功能），即平台调用SDK下发给NVR
	public void setTags() {
		NetSDKLib.NET_IN_FILE_STREAM_TAGS_INFO inFileSetTags = new NetSDKLib.NET_IN_FILE_STREAM_TAGS_INFO();
		
		int nArrayCount = 2; 
		NetSDKLib.NET_FILE_STREAM_TAG_INFO[] fileTagsArr = new NetSDKLib.NET_FILE_STREAM_TAG_INFO[nArrayCount];
		for(int i=0; i<fileTagsArr.length; i++) {
			fileTagsArr[i] = new NetSDKLib.NET_FILE_STREAM_TAG_INFO();
		}											
		
		inFileSetTags.nArrayCount = nArrayCount;
		inFileSetTags.pstuTagInfo = new Memory(nArrayCount*fileTagsArr[0].size());
		inFileSetTags.pstuTagInfo.clear(nArrayCount*fileTagsArr[0].size());

		System.arraycopy("Text1".getBytes(), 0, fileTagsArr[0].szContext, 0, "Text1".getBytes().length);
		System.arraycopy("admin".getBytes(), 0, fileTagsArr[0].szUserName, 0, "admin".getBytes().length);
		System.arraycopy("1".getBytes(), 0, fileTagsArr[0].szChannelName, 0, "1".getBytes().length);
		
		// 有视频的时间段内，时间要在查询句柄的时间内
		fileTagsArr[0].stuTime.dwYear = 2016;
		fileTagsArr[0].stuTime.dwMonth = 11;
		fileTagsArr[0].stuTime.dwDay = 16;
		fileTagsArr[0].stuTime.dwHour = 23;
		fileTagsArr[0].stuTime.dwMinute = 17;
		fileTagsArr[0].stuTime.dwSecond = 0;
		
		System.arraycopy("Text2".getBytes(), 0, fileTagsArr[1].szContext, 0, "Text2".getBytes().length);
		System.arraycopy("admin".getBytes(), 0, fileTagsArr[1].szUserName, 0, "admin".getBytes().length);
		System.arraycopy("1".getBytes(), 0, fileTagsArr[1].szChannelName, 0, "1".getBytes().length);
		fileTagsArr[1].stuTime.dwYear = 2016;
		fileTagsArr[1].stuTime.dwMonth = 11;
		fileTagsArr[1].stuTime.dwDay = 16;
		fileTagsArr[1].stuTime.dwHour = 23;
		fileTagsArr[1].stuTime.dwMinute = 30;
		fileTagsArr[1].stuTime.dwSecond = 0;
		
		NetSDKTools.SetStructArrToPointerData(fileTagsArr, inFileSetTags.pstuTagInfo);
		
		NetSDKLib.NET_OUT_FILE_STREAM_TAGS_INFO outFileSetTags = new NetSDKLib.NET_OUT_FILE_STREAM_TAGS_INFO();
		
		inFileSetTags.write();
		outFileSetTags.write();
		boolean bRet = NetSdk.CLIENT_FileStreamSetTags(m_hFindHandle, inFileSetTags, outFileSetTags, 8000);
		inFileSetTags.read();
		outFileSetTags.write();
		if(bRet) {
			System.out.println("SetTags Succeed!");
		} else {
			System.err.println("SetTags Failed!" +NetSdk.CLIENT_GetLastError());
		}
	}
	
	// 查询设备序列号
	public void queryDevSerialNo() {
		int nType = NetSDKLib.NET_DEVSTATE_SOFTWARE;
		NetSDKLib.NETDEV_VERSION_INFO devVersionInfo = new NetSDKLib.NETDEV_VERSION_INFO();
    	IntByReference intRetLen = new IntByReference();
    	
    	devVersionInfo.write();
		boolean bRet = NetSdk.CLIENT_QueryDevState(m_hLoginHandle, nType, devVersionInfo.getPointer(), devVersionInfo.size(), intRetLen.getPointer(), 3000);
		devVersionInfo.read();
		
		if(bRet) {
			System.out.println("QueryDev Succeed!" + new String(devVersionInfo.szDevSerialNo).trim());
		} else {
			System.err.println("QueryDev Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	// 查询录像视频
	public void queryRecordFile() {
		NetSDKLib.NET_TIME stTimeStart = new NetSDKLib.NET_TIME();
		stTimeStart.dwYear = 2016;
		stTimeStart.dwMonth = 12;
		stTimeStart.dwDay = 1;
		stTimeStart.dwHour =11;
		stTimeStart.dwMinute = 30;
		stTimeStart.dwSecond = 0;
		
		NetSDKLib.NET_TIME stTimeEnd = new NetSDKLib.NET_TIME();
		stTimeEnd.dwYear = 2016;
		stTimeEnd.dwMonth = 12;
		stTimeEnd.dwDay = 1;
		stTimeEnd.dwHour = 12;
		stTimeEnd.dwMinute = 0;
		stTimeEnd.dwSecond = 0;
		
		//**************按时间查找视频文件**************
		int nFileCount = 200; //每次查询的最大文件个数
		NetSDKLib.NET_RECORDFILE_INFO[] numberFile = (NetSDKLib.NET_RECORDFILE_INFO[])new NetSDKLib.NET_RECORDFILE_INFO().toArray(nFileCount);
		int maxlen = nFileCount * numberFile[0].size();

		IntByReference outFileCoutReference = new IntByReference(0);
		
		boolean cRet = NetSdk.CLIENT_QueryRecordFile(m_hLoginHandle, 0, 0, stTimeStart, stTimeEnd, null, numberFile, maxlen, outFileCoutReference, 5000, false);
//		NetSDKTools.GetPointerDataToStructArr(stFileInfo, numberFile);
		
		if(cRet) {
			System.out.println("QueryRecordFile  Succeed! \n" + "查询到的视频个数：" + outFileCoutReference.getValue() 
							   + "\n" + "码流类型：" + numberFile[0].bRecType);
			System.out.printf("%s", numberFile[0].filename);
																
		} else {
			System.err.println("QueryRecordFile  Failed!" + NetSdk.CLIENT_GetLastError());
		}
		
		// *********查询时间段内是否有视频*************
		/*IntByReference bResult = new IntByReference(0);
		boolean cRet = NetSdk.CLIENT_QueryRecordTime(m_hLoginHandle, 0, 0, stTimeStart, stTimeEnd, null, bResult, 5000);
		if(cRet) {
			System.out.printf("QueryRecordFile  Succeed!\n bResult = %b", bResult.getValue());																	
		} else {
			System.err.println("QueryRecordFile  Failed!" + NetSdk.CLIENT_GetLastError());
		}*/
	}
	
	// 主动查询视频丢失
	private void queryDev(){
		int nType = NetSDKLib.NET_DEVSTATE_VIDEOLOST ;
		NetSDKLib.NET_CLIENT_VIDEOLOST_STATE clientState = new NetSDKLib.NET_CLIENT_VIDEOLOST_STATE();
		int nBufLen = clientState.size();
		
		IntByReference intRetLen = new IntByReference();
		clientState.write();
		boolean zRet = NetSdk.CLIENT_QueryDevState(m_hLoginHandle, nType, clientState.getPointer(), nBufLen, intRetLen.getPointer(), 5000);	
		clientState.read();
		if(zRet) {
			System.out.println("QueryDevState Succeed! \r\n" + "channelcount = " + clientState.channelcount);
			for (int i = 0; i< clientState.channelcount; ++i) 
			{
				System.out.println("dwAlarmState[" + i + "] = " + ((clientState.dwAlarmState[0] >> i) & 0x01)); // 1-视频丢失; 0-无视频丢失
			}	
			
		} else {
			System.err.println("QueryDevState Failed! " + NetSdk.CLIENT_GetLastError());
		}
	}
	
	// 被动查询视频丢失，通过监听回调实现
	private void startListen(){	
	    // 设置报警回调函数
		NetSdk.CLIENT_SetDVRMessCallBack(m_AlarmDataCB, new NativeLong(0));
		
		// 订阅报警
		boolean bRet = NetSdk.CLIENT_StartListenEx(m_hLoginHandle);
		if (!bRet) {
			System.out.println(String.format("Subscrible alarm event failed! LastError = 0x%x\n", NetSdk.CLIENT_GetLastError()));
		}
		else {
			System.out.println("Subscrible alarm event success");
		}
	}
	
	fAlarmDataCB m_AlarmDataCB = new fAlarmDataCB();
	private class fAlarmDataCB implements NetSDKLib.fMessCallBack {
		@Override
		public boolean invoke(NativeLong lCommand, NativeLong lLoginID, Pointer pStuEvent, int dwBufLen, 
							  String strDeviceIP, NativeLong nDevicePort, NativeLong dwUser) {
					
			switch (lCommand.intValue()) {
			case NetSDKLib.NET_VIDEOLOST_ALARM_EX :
				
				System.out.println("dwBufLen = " + dwBufLen);
				System.out.printf("0x%x\n", lCommand.intValue());
				
				if (dwBufLen > 0) {
					byte[] channelState = pStuEvent.getByteArray(0, dwBufLen);  // 将缓存pStuEvent的值，按byte[]输出
					for (int i = 0; i < dwBufLen; i++) {
						System.out.println("Channel[" + i + "] Lost Vedio = " + (channelState[i]));  // 1-视频丢失; 0-无视频丢失
					}
				}
				break;
			default :
				break;
			}		
			return true;
		}
	}
	
	// 开闸事件
	private void openStore() {
		NetSDKLib.NET_CTRL_OPEN_STROBE openStrobe = new NetSDKLib.NET_CTRL_OPEN_STROBE();
		openStrobe.nChannelId = 0;
		String plate = new String("浙A.8888");

		System.arraycopy(plate.getBytes(), 0, openStrobe.szPlateNumber, 0, plate.getBytes().length);
		openStrobe.write();

		boolean openRet = NetSdk.CLIENT_ControlDevice(m_hLoginHandle, NetSDKLib.CtrlType.CTRLTYPE_CTRL_OPEN_STROBE, openStrobe.getPointer(), 3000);
		openStrobe.read();
		if(openRet)
		{
		    System.out.println("OpenStore Success!");
		} else {
			System.err.println("OpenStore Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	// 语音下发
	private void recordUp(){   	
    	NetSDKLib.NET_IN_UPLOAD_REMOTE_FILE inUploadFile = new NetSDKLib.NET_IN_UPLOAD_REMOTE_FILE();
    	inUploadFile.pszFileDst = new String("y.mp3");      // 目标文件路径,文件格式不固定
    	inUploadFile.pszFolderDst = null; //new String("/user/data/AudioFiles"); // 目标文件夹路径,null时，为默认路径
    	inUploadFile.pszFileSrc = new String("d:\\y.mp3");   // 源文件路径
    	
    	inUploadFile.nPacketLen = 1024*2; // 针对语音下发，这个必须是1024*2
    	NetSDKLib.NET_OUT_UPLOAD_REMOTE_FILE outUploadFile = new NetSDKLib.NET_OUT_UPLOAD_REMOTE_FILE();
    	
    	inUploadFile.write();
    	boolean bRet = NetSdk.CLIENT_UploadRemoteFile(m_hLoginHandle, inUploadFile, outUploadFile, 3000);
    	inUploadFile.read();
    	if (bRet) {
    		System.out.println("upload Remote ok");
    	}else {
    		System.err.println("upload Remote Error" + NetSdk.CLIENT_GetLastError());
    		return;
    	}
	}
	
	// 过车记录订阅，上传卡号协议
	public void parkCard(){
		NetSDKLib.NET_IN_PARKING_CONTROL_PARAM pInParam = new NetSDKLib.NET_IN_PARKING_CONTROL_PARAM();
		pInParam.cbCallBack = fParkingcb;
		
		NetSDKLib.NET_OUT_PARKING_CONTROL_PARAM pOutParam = new NetSDKLib.NET_OUT_PARKING_CONTROL_PARAM();
		m_hAttachHandle = NetSdk.CLIENT_ParkingControlAttachRecord(m_hLoginHandle, pInParam, pOutParam, 3000);
		
		if(m_hAttachHandle.longValue() == 0) {
			System.err.println("过车记录订阅失败" + NetSdk.CLIENT_GetLastError());
		} else {
			System.out.println("过车记录订阅成功");
		}
	}
	
	private ParkingControlRecordCB fParkingcb = new ParkingControlRecordCB();
	// 订阅过车记录数据回调函数原型
	public class ParkingControlRecordCB implements NetSDKLib.fParkingControlRecordCallBack {
		public void invoke(NativeLong lLoginID, NativeLong lAttachHandle,
				NetSDKLib.NET_CAR_PASS_ITEM pInfo, int nBufLen, NativeLong dwUser) {
			
			System.out.println("卡号:" + pInfo.dwCardNo + "\n IC卡用户类型：" + pInfo.emCardType + "\n 过车记录类型：" + pInfo.emFlag);
		}	
	}
	
	// 车位状态订阅
	public void attachPark(){
		NetSDKLib.NET_IN_PARK_INFO_PARAM parkIn = new NetSDKLib.NET_IN_PARK_INFO_PARAM();
		parkIn.stuFilter.dwNum = 10;
		parkIn.stuFilter.emType[0] = NetSDKLib.NET_ECK_PARK_DETECTOR_TYPE.NET_ECK_PARK_DETECTOR_TYPE_ALL;
		parkIn.cbCallBack = parkInfoCB;
		
		NetSDKLib.NET_OUT_PARK_INFO_PARAM parkOut = new NetSDKLib.NET_OUT_PARK_INFO_PARAM();
		parkIn.write();
		parkOut.write();
		m_hAttachParkHandle = NetSdk.CLIENT_ParkingControlAttachParkInfo(m_hLoginHandle, parkIn, parkOut, 3000);
		parkIn.read();
		parkOut.read();
		
		if(0 != m_hAttachParkHandle.longValue()) {
			System.out.println("AttachPark Succeed! \r\n");
		} else {
			System.err.println("AttachPark Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	private ParkInfoCB parkInfoCB = new ParkInfoCB();
    // 订阅车位信息回调函数原型
	public class ParkInfoCB implements NetSDKLib.fParkInfoCallBack {
		public void invoke(NativeLong lLoginID, NativeLong lAttachHandle,
				NetSDKLib.NET_PARK_INFO_ITEM pInfo, int nBufLen, NativeLong dwUser) {
			System.out.println("车位号: " + new String(pInfo.szParkNo).trim() + "\n");   // 车位号
			System.out.println("位号显示对应的诱导屏分屏号 : " + pInfo.dwScreenIndex + "\n"); // 位号显示对应的诱导屏分屏号
			System.out.println("屏号显示的当前空余车位数目 : " + pInfo.dwFreeParkNum + "\n");  // 屏号显示的当前空余车位数目
			
			// 车位状态
			switch(pInfo.emState) {
			case NetSDKLib.NET_ECK_PARK_STATE.NET_ECK_PARK_STATE_PARK:
				System.out.println("车位状态：有车位" + "\n");
				break;
			case NetSDKLib.NET_ECK_PARK_STATE.NET_ECK_PARK_STATE_NOPARK:
				System.out.println("车位状态：无车位" + "\n");
				break;
			default :
				break;
			}		
		}	
	}
	
	// 取消车位状态订阅
	public void detachPark(){
		boolean bRet = NetSdk.CLIENT_ParkingControlDetachParkInfo(m_hAttachParkHandle);
		if(bRet) {
			System.out.println("DetachPark Succeed! \r\n");
		} else {
			System.err.println("DetachPark Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	/*
	 * 下发到诱导屏
	 */
	public void setParkInfo() {
		int emType = NetSDKLib.CtrlType.CTRLTYPE_CTRL_ECK_SET_PARK_INFO;   // 智能停车系统出入口机设置车位信息
		NetSDKLib.NET_CTRL_ECK_SET_PARK_INFO_PARAM ctrlSetParkInfo = new NetSDKLib.NET_CTRL_ECK_SET_PARK_INFO_PARAM();
		ctrlSetParkInfo.nScreenNum = 3;    // 屏数量，不能大于8
		
		ctrlSetParkInfo.nScreenIndex[0] = 0;  // 屏号
		ctrlSetParkInfo.nFreeParkNum[0] = 5;  // 对应屏显示的空余车位数
		
//		ctrlSetParkInfo.nScreenIndex[1] = 1;  // 屏号
//		ctrlSetParkInfo.nFreeParkNum[1] = 11;  // 对应屏显示的空余车位数
				
//		ctrlSetParkInfo.nScreenIndex[2] = 2;  // 屏号
//		ctrlSetParkInfo.nFreeParkNum[2] = 11;  // 对应屏显示的空余车位数
		
		ctrlSetParkInfo.write();
		
		boolean  bRet = NetSdk.CLIENT_ControlDevice(m_hLoginHandle, emType, ctrlSetParkInfo.getPointer(), 3000);
		
		ctrlSetParkInfo.read();
		
		if(bRet) {
			System.out.println("SetParkInfo Succeed!");
		} else {
			System.err.printf("SetParkInfo Failed! %x\n", NetSdk.CLIENT_GetLastError());
		}
	}
	
	
	/*
	 * 大屏开关控制
	 */
	public void powerControl() {
		NetSDKLib.NET_IN_WM_POWER_CTRL inPowerCtrl = new NetSDKLib.NET_IN_WM_POWER_CTRL();
		inPowerCtrl.nMonitorWallID = 0; // 电视墙序号
		inPowerCtrl.pszBlockID = null;  // null/""-所有区块
		inPowerCtrl.nTVID = -1;   // -1表示区块中所有显示单元
		inPowerCtrl.bPowerOn = 1; // 1是开，0是关
		
		NetSDKLib.NET_OUT_WM_POWER_CTRL outPowerCtrl = new NetSDKLib.NET_OUT_WM_POWER_CTRL();
		
		inPowerCtrl.write();
		outPowerCtrl.write();
		boolean bPowerCtr = NetSdk.CLIENT_PowerControl(m_hLoginHandle, inPowerCtrl, outPowerCtrl, 3000);
		inPowerCtrl.read();
		outPowerCtrl.read();
		
		if(bPowerCtr) {
			System.out.println("PowerControl Succeed!");
		} else {
			System.err.println("PowerControl Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	/*
	 * 得到模式列表，获取电视墙预案
	 */
	public void getMonitorWallCollections() {
		NetSDKLib.NET_IN_WM_GET_COLLECTIONS inGetMonitor = new NetSDKLib.NET_IN_WM_GET_COLLECTIONS();
		inGetMonitor.nMonitorWallID = 0; //电视墙ID
		
		NetSDKLib.NET_OUT_WM_GET_COLLECTIONS outGetMonitor = new NetSDKLib.NET_OUT_WM_GET_COLLECTIONS();
		// 建立 NET_MONITORWALL_COLLECTION 数组
		int nCollecCount = 3; // 查询的预案数量的最大值,如果设置的过大，会溢出，需要在eclipse里设置，增加堆内存
//		NetSDKLib.NET_MONITORWALL_COLLECTION[] monitorwallArr = 
//			      (NetSDKLib.NET_MONITORWALL_COLLECTION[])new NetSDKLib.NET_MONITORWALL_COLLECTION().toArray(nCollecCount); 
		NetSDKLib.NET_MONITORWALL_COLLECTION[] monitorwallArr = new NetSDKLib.NET_MONITORWALL_COLLECTION[nCollecCount];
		for(int i=0; i<monitorwallArr.length; i++) {
			monitorwallArr[i] =  new NetSDKLib.NET_MONITORWALL_COLLECTION();
		}
		
		outGetMonitor.nMaxCollectionsCount = nCollecCount * monitorwallArr[0].size(); // 电视墙预案数组大小
		
		outGetMonitor.pCollections = new Memory(outGetMonitor.nMaxCollectionsCount);       // 初始化Pointer指针
		outGetMonitor.pCollections.clear(outGetMonitor.nMaxCollectionsCount);
		
		NetSDKTools.SetStructArrToPointerData(monitorwallArr, outGetMonitor.pCollections); // 将数组内存拷贝给指针

		boolean bGetMonitor = NetSdk.CLIENT_GetMonitorWallCollections(m_hLoginHandle, inGetMonitor, outGetMonitor, 5000);
		
		NetSDKTools.GetPointerDataToStructArr(outGetMonitor.pCollections, monitorwallArr); // 将指针的值放入数组
		
		if(bGetMonitor) {
			System.out.println("GetMonitorWallCollections Succeed!" + "\n" + "电视墙预案数量：" + outGetMonitor.nCollectionsCount + "\n");
			System.out.println("显示源数组大小：" + outGetMonitor.nMaxCollectionsCount);
			for(int i=0; i<outGetMonitor.nCollectionsCount; i++) {
				System.out.println("电视墙预案名称：" + new String(monitorwallArr[i].szName).trim());
				System.out.println("控制ID：" + new String(monitorwallArr[i].szControlID).trim());
				System.out.println();
			}
		} else {
			System.err.println("GetMonitorWallCollections Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	/*
	 * 调用模式
	 */
	public void LoadMonitorWallCollection() {
		// 载入预案********
		NetSDKLib.NET_IN_WM_LOAD_COLLECTION inLoad = new NetSDKLib.NET_IN_WM_LOAD_COLLECTION();
		inLoad.nMonitorWallID = 0;  //电视墙ID
		inLoad.pszName = "0";   	// 预案名称
		
		NetSDKLib.NET_OUT_WM_LOAD_COLLECTION outLoad = new NetSDKLib.NET_OUT_WM_LOAD_COLLECTION();
		
		boolean bLoad = NetSdk.CLIENT_LoadMonitorWallCollection(m_hLoginHandle, inLoad, outLoad, 3000);

		if(bLoad) {
			System.out.println("LoadMonitorWallCollection Succeed!");
		} else {
			System.err.println("LoadMonitorWallCollection Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	public void SaveMonitorWallCollection() {		
		// 保存预案********
		NetSDKLib.NET_IN_WM_SAVE_COLLECTION inSave = new NetSDKLib.NET_IN_WM_SAVE_COLLECTION();
		inSave.nMonitorWallID = 0; //电视墙ID
		inSave.pszName = "0"; // 预案名称
		inSave.pszControlID = "1"; // 控制ID，这个要与上面的预案名称对应
		
		NetSDKLib.NET_OUT_WM_SAVE_COLLECTION outSave = new NetSDKLib.NET_OUT_WM_SAVE_COLLECTION();
		
		boolean bSave = NetSdk.CLIENT_SaveMonitorWallCollection(m_hLoginHandle, inSave, outSave, 3000);
		
		if(bSave) {
			System.out.println("SaveMonitorWallCollection Succeed!");
		} else {
			System.err.println("SaveMonitorWallCollection Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	/*
	 * 切换信号，信号切换是在调用模式后使用    // 查询显示源
	 */
	public void getSplitSource() {
		int nChannel = 130; // 输出通道号
		int nWindow = -1;   // 输出通道对应的窗口号， -1表示所有窗口
		
		int maxCount = 10; // 设置显示源数组的最大个数
		NetSDKLib.NET_SPLIT_SOURCE[] splitSourceArr = (NetSDKLib.NET_SPLIT_SOURCE[])new NetSDKLib.NET_SPLIT_SOURCE().toArray(maxCount);
		int nMaxCount = maxCount * splitSourceArr[0].size();
		
		IntByReference pnRetCount = new IntByReference(0);  // 返回的显示源数量 
		
		boolean bGetSplit = NetSdk.CLIENT_GetSplitSource(m_hLoginHandle, nChannel, nWindow, splitSourceArr, nMaxCount, pnRetCount, 5000);

		
		if(bGetSplit) {
			System.out.println("GetSplitSource Succeed!" + "\n" + "显示源数量:" + pnRetCount.getValue());
			for(int i=0; i<pnRetCount.getValue(); i++) {
				System.out.println("设备协议类型:" + splitSourceArr[i].emProtocol + "\n"
									+"码流类型:" + splitSourceArr[i].emPushStream + "\n"
									+ "通道号：" + splitSourceArr[i].nChannelID + "\n");
			}
		} else {
			System.err.println("GetSplitSource Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}

	public void setSplitSource() {
		// 设置显示源
		int nChannel = 130; // 输出通道号
		int nWindow = -1;   // 输出通道对应的窗口号， -1表示所有窗口
		
		int nSrcCount = 1; // 设置显示源数组的个数(此接口用于设置一个显示源)
		NetSDKLib.NET_SPLIT_SOURCE setsplitSource = new NetSDKLib.NET_SPLIT_SOURCE();

		setsplitSource.bEnable = 1;

		
		boolean bSetSplit = NetSdk.CLIENT_SetSplitSource(m_hLoginHandle, nChannel, nWindow, setsplitSource, nSrcCount, 3000);
		if(bSetSplit) {
			System.out.println("SetSplitSource Succeed!");
		} else {
			System.err.println("SetSplitSource Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	// 远程抓图
	public void snapPicture()
	{
		//设置抓图回调函数， 图片主要在m_SnapReceiveCB中返回
		NetSdk.CLIENT_SetSnapRevCallBack(m_SnapReceiveCB, new NativeLong(0));
    	
		// 发送抓图命令给前端设备，抓图的信息
		NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS() ; 
		stuSnapParams.Channel = 0;  //抓图通道
		stuSnapParams.mode = 0;     //表示请求一帧 
		stuSnapParams.CmdSerial = 0; // 请求序列号，有效值范围 0~65535，超过范围会被截断为 
		
		int reserved[] = {0};
		
		if (false == NetSdk.CLIENT_SnapPictureEx(m_hLoginHandle, stuSnapParams , reserved)) 
		{ 
			System.out.printf("CLIENT_SnapPictureEx Failed!Last Error[%x]\n", NetSdk.CLIENT_GetLastError());
			return;
		} 
		else 
		{ 
			System.out.println("CLIENT_SnapPictureEx success"); 
		}
	}
	
	private fSnapReceiveCB  	m_SnapReceiveCB  	= new fSnapReceiveCB();
	public class fSnapReceiveCB implements NetSDKLib.fSnapRev{
		public void invoke( NativeLong lLoginID ,Pointer pBuf, int RevLen, int EncodeType, NativeLong CmdSerial, NativeLong dwUser)
		{
			//pBuf收到的图片数据
			File currentPath = new File(".");
			String strFileName = currentPath.getAbsoluteFile().getParent() + "\\" + System.currentTimeMillis() + ".jpg"; 
			//保存图片到本地文件
			NetSDKTools.savePicture(pBuf , RevLen , strFileName); 
			System.out.printf("Get Picture EncodeType = %d CmdSerial=%d\n", EncodeType , CmdSerial.intValue());
			System.out.println("strFileName : " + strFileName);
		}
	}
	
	/*
	 * 报警输出控制   二代协议
	 */
	public void queryAlarmOut() {
		boolean bRet = false;
		int emType = NetSDKLib.NET_IOTYPE.NET_ALARMOUTPUT;
		
		// 获取报警输出通道个数
		IntByReference nIOCountChannel = new IntByReference(0);
		bRet = NetSdk.CLIENT_QueryIOControlState(m_hLoginHandle, emType, null, 0, nIOCountChannel, 5000);
		if(bRet) {
			System.out.println("报警输出通道个数 : " + nIOCountChannel.getValue());
		}
		
		
		/// 获取报警输出通道状态
		int numChannel = nIOCountChannel.getValue();  // 通道数
		/// 构建一个数组，并初始化
		NetSDKLib.ALARM_CONTROL[] alarmControl = new NetSDKLib.ALARM_CONTROL[numChannel];
		for(int i=0; i<alarmControl.length; i++) {
			alarmControl[i] = new NetSDKLib.ALARM_CONTROL();
		}
		
		/// 分配内存
		int maxlen = numChannel * alarmControl[0].size();
		Pointer pState = new Memory(maxlen);
		pState.clear(maxlen);
		
		/// 将结构体数组拷贝到内存
		NetSDKTools.SetStructArrToPointerData(alarmControl, pState);
		IntByReference nIOCount = new IntByReference(0);
		bRet = NetSdk.CLIENT_QueryIOControlState(m_hLoginHandle, emType, pState, maxlen, nIOCount, 5000);
		NetSDKTools.GetPointerDataToStructArr(pState, alarmControl);
		if(bRet) {
			System.out.println("nIOCount : " + nIOCount.getValue());
			for(int j=0; j<nIOCount.getValue(); j++){
				System.out.println("state : " + alarmControl[j].state);
			}
		} else {
			System.err.println("Get Failed" + NetSdk.CLIENT_GetLastError());
		}	
	}
	
	/// 设置报警输出
	public void alarmOutControl() {
		boolean bRet = false;
		int emType = NetSDKLib.NET_IOTYPE.NET_ALARMOUTPUT;
		
		// 获取报警输出通道个数
		IntByReference nIOCountChannel = new IntByReference(0);
		bRet = NetSdk.CLIENT_QueryIOControlState(m_hLoginHandle, emType, null, 0, nIOCountChannel, 5000);
		if(bRet) {
			System.out.println("报警输出通道个数 : " + nIOCountChannel.getValue());
		}
		
		int numChannel = nIOCountChannel.getValue();  // 通道数
		/// 构建一个数组，并初始化
		NetSDKLib.ALARM_CONTROL[] alarmControl = new NetSDKLib.ALARM_CONTROL[numChannel];
		for(int i=0; i<alarmControl.length; i++) {
			alarmControl[i] = new NetSDKLib.ALARM_CONTROL();
		}
		
		/// 分配内存
		int maxlen = numChannel * alarmControl[0].size();
		Pointer pState = new Memory(maxlen);
		pState.clear(maxlen);
		
		alarmControl[0].state = 1;
		alarmControl[1].state = 1;
		
		/// 将结构体数组拷贝到内存
		NetSDKTools.SetStructArrToPointerData(alarmControl, pState);
	
		bRet = NetSdk.CLIENT_IOControl(m_hLoginHandle, emType, pState, maxlen);
		if(bRet) {
			System.out.println("Set Succeed!");
		} else {
			System.err.println("Set Failed" + NetSdk.CLIENT_GetLastError());
		}	
	}
	
	/*
	 * 报警输出配置  三代协议
	 */
	public void alarmOutInfo() {
		boolean bRet = false;
		int emType = NetSDKLib.NET_IOTYPE.NET_ALARMOUTPUT;
		
		// 获取报警输出通道个数
		IntByReference nIOCountChannel = new IntByReference(0);
		bRet = NetSdk.CLIENT_QueryIOControlState(m_hLoginHandle, emType, null, 0, nIOCountChannel, 5000);
		if(bRet) {
			System.out.println("报警输出通道个数 : " + nIOCountChannel.getValue());
		}
		
				
		int nChn = nIOCountChannel.getValue();
		String strCmd = NetSDKLib.CFG_CMD_ALARMOUT;
		NetSDKLib.CFG_ALARMOUT_INFO alarmOutInfo = new NetSDKLib.CFG_ALARMOUT_INFO();
		for(int i=0; i<nChn; i++) {
			// 获取状态
			bRet= false;
			bRet = NetSDKTools.GetDevConfig(m_hLoginHandle, i, strCmd, alarmOutInfo);  // 获取单个通道的信息
			if(bRet) {
				System.out.println("nChannelID : " + alarmOutInfo.nChannelID);
				System.out.println("nOutputMode : " + alarmOutInfo.nOutputMode);
			}
			
			// 设置
			bRet = false;
			alarmOutInfo.nChannelID = i;
			if(alarmOutInfo.nChannelID == 0) {
				alarmOutInfo.nOutputMode = 1;
			} else if(alarmOutInfo.nChannelID == 1){
				alarmOutInfo.nOutputMode = 0;
			}

			bRet = NetSDKTools.SetDevConfig(m_hLoginHandle, i, strCmd, alarmOutInfo);    // 设置单个通道的信息
			if(bRet) {
				System.out.println("Set Succeed!");
			}
		}				
	}
	
	/*
	 * 订阅监测点位信息   "SCADA.attach"     数据上报
	 */
	public void scadaAttachInfo() {
		if(m_lAttachHandle.longValue() != 0) {
			if(NetSdk.CLIENT_SCADADetachInfo(m_lAttachHandle)) {
				System.out.println("DetachInfo Succeed!");
			} else {
				System.err.println("DetachInfo Failed!" + NetSdk.CLIENT_GetLastError());
			}
		}
		
		
		NetSDKLib.NET_IN_SCADA_ATTACH_INFO pInParam = new NetSDKLib.NET_IN_SCADA_ATTACH_INFO();
		pInParam.cbCallBack = new fSCADAAttachInfoCB();
		pInParam.emPointType = NetSDKLib.EM_NET_SCADA_POINT_TYPE.EM_NET_SCADA_POINT_TYPE_ALL;
		NetSDKLib.NET_OUT_SCADA_ATTACH_INFO pOutParam = new NetSDKLib.NET_OUT_SCADA_ATTACH_INFO();
		
		m_lAttachHandle = NetSdk.CLIENT_SCADAAttachInfo(m_hLoginHandle, pInParam, pOutParam, 3000);
		if(0 != m_lAttachHandle.longValue()) {
			System.out.println("AttachInfo Succeed!");
		} else {
			System.err.println("AttachInfo Failed!" + NetSdk.CLIENT_GetLastError());
		}
		
	}
	
	public class fSCADAAttachInfoCB implements NetSDKLib.fSCADAAttachInfoCallBack {
		@Override
		public void invoke(NativeLong lLoginID, NativeLong lAttachHandle,
				NetSDKLib.NET_SCADA_NOTIFY_POINT_INFO_LIST pInfo, int nBufLen, NativeLong dwUser) {
			System.out.println("nList : " + pInfo.nList);
			for(int i=0; i<pInfo.nList; i++) {
				System.out.println("emPointType : " + pInfo.stuList[i].emPointType);
				System.out.println("szPointName : " + new String(pInfo.stuList[i].szPointName).trim());
			}
		}
		
	}
	
	/*
	 * 限速设置
	 */
	public void trafficSnapshot() {
		boolean bRet = false;
//		int nLowSpeed = 0;
//		int nHignSpeed = 60;
		String strCmd = NetSDKLib.CFG_CMD_INTELLECTIVETRAFFIC;
		NetSDKLib.CFG_TRAFFICSNAPSHOT_INFO trafficSnapshot = new NetSDKLib.CFG_TRAFFICSNAPSHOT_INFO();
		bRet = NetSDKTools.GetDevConfig(m_hLoginHandle, 0, strCmd, trafficSnapshot);
		if(bRet) {
//			System.out.print("nLowSpeed : " + trafficSnapshot.arstDetector[0].arnSmallCarSpeedLimit[0]);
//			System.out.print("nHignSpeed :" + trafficSnapshot.arstDetector[0].arnSmallCarSpeedLimit[1]);
			System.out.print("nParkType :" + trafficSnapshot.nParkType + "\n");
		} else {
			System.err.println("Get SpeedLimit Failed!" + NetSdk.CLIENT_GetLastError());
		}

		
		bRet = false;
//		trafficSnapshot.arstDetector[0].arnSmallCarSpeedLimit[0] = nLowSpeed;
//		trafficSnapshot.arstDetector[0].arnSmallCarSpeedLimit[1] = nHignSpeed;

		trafficSnapshot.nParkType = 2;

		bRet = NetSDKTools.SetDevConfig(m_hLoginHandle, 0, strCmd, trafficSnapshot);

		if(bRet) {
			System.out.print("Set SpeedLimit Succeed! \n");
		} else {
			System.err.println("Set SpeedLimit Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}

	/*
	 * 透明串口
	 */
	public void transComChannel() {	
		if(m_TransComChannel.longValue() != 0) { 
			NetSdk.CLIENT_DestroyTransComChannel(m_TransComChannel);
		}
		
		// 创建透明串口通道, 用于接收数据
		int TransComType1 = 1;  // 0:串口(232)， 1:485口
		int baudrate = 4;  // 1~8分别表示 1200 2400  4800 9600 19200 38400 57600 115200
		int databits = 8;  // 4~8表示4位~8位 
		int stopbits = 1;  // 232串口 ： 数值0 代表停止位1; 数值1 代表停止位1.5; 数值2 代表停止位2.    485串口 ： 数值1 代表停止位1; 数值2 代表停止位2.
		int parity = 0;    // 0：无校验，1：奇校验；2：偶校验;
		m_TransComChannel = NetSdk.CLIENT_CreateTransComChannel(m_hLoginHandle, TransComType1, baudrate, databits, stopbits, parity, cbTransCom, new NativeLong(0));
		if(m_TransComChannel.longValue() != 0) {
			System.out.println("CLIENT_CreateTransComChannel Succeed!" + m_TransComChannel.longValue());
		} else {
			System.err.println("CLIENT_CreateTransComChannel Failed!" + NetSdk.CLIENT_GetLastError());
		}
		
		// 透明串口发送数据
		int bufferSize = 10;  // 可变
		byte pBuffer[] = new byte[bufferSize];
		pBuffer[0] = 'a';
		pBuffer[1] = 'b';
		pBuffer[2] = 'c';
		pBuffer[3] = 'd';
		pBuffer[4] = 'e';
		pBuffer[5] = 'f';
		pBuffer[6] = 'g';
		pBuffer[7] = 'h';
		pBuffer[8] = 'i';
		pBuffer[9] = 'j';
		if(NetSdk.CLIENT_SendTransComData(m_TransComChannel, pBuffer, pBuffer.length)) {
			System.out.println("CLIENT_SendTransComData Succeed!");
		} else {
			System.err.println("CLIENT_SendTransComData Failed!" + NetSdk.CLIENT_GetLastError());
		}
	}
	
	TestTransComCallBack cbTransCom = new TestTransComCallBack();
	public class TestTransComCallBack implements NetSDKLib.fTransComCallBack{
		@Override
		public void invoke(NativeLong lLoginID, NativeLong lTransComChannel,
			Pointer pBuffer, int dwBufSize, NativeLong dwUser) {
				
			byte[] buffer = pBuffer.getByteArray(0, dwBufSize);   // 将Pointer转为byte数组
			
			for(int i=0; i<dwBufSize; i++) {
				System.out.printf(Integer.toHexString( (buffer[i] & 0x000000ff) | 0xffffff00).substring(6) + " ");  // 十六进制输出
			}
		}	
	}
	
	///查询全部门禁用户信息
	public void findAllAccess() {
		NetSDKLib.NET_IN_FIND_RECORD_PARAM stuFindInParam = new NetSDKLib.NET_IN_FIND_RECORD_PARAM();
		stuFindInParam.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; 
		
		NetSDKLib.NET_OUT_FIND_RECORD_PARAM stuFindOutParam = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM();
	
		if(NetSdk.CLIENT_FindRecord(m_hLoginHandle, stuFindInParam, stuFindOutParam, 5000)) {

			System.out.println("FindRecord Succeed" + "\n" + "FindHandle :" + stuFindOutParam.lFindeHandle);

			int count = 0;  //循环的次数
			int nFindCount = 0;	
			int nRecordCount = 10;  // 每次查询的个数
			NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARD[] pstRecord = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARD[nRecordCount];
			for(int i=0; i<nRecordCount; i++) {
				pstRecord[i] = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARD();
			}
			
			NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM stuFindNextInParam = new NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM();
			stuFindNextInParam.lFindeHandle = stuFindOutParam.lFindeHandle;
			stuFindNextInParam.nFileCount = nRecordCount;  //想查询的记录条数
			
			NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM stuFindNextOutParam = new NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM();
			stuFindNextOutParam.nMaxRecordNum = nRecordCount;
			stuFindNextOutParam.pRecordList = new Memory(pstRecord[0].dwSize * nRecordCount);
			stuFindNextOutParam.pRecordList.clear(pstRecord[0].dwSize * nRecordCount);	
			
			NetSDKTools.SetStructArrToPointerData(pstRecord, stuFindNextOutParam.pRecordList);	//将数组内存拷贝给Pointer指针	
			
			while(true) {  //循环查询				
				if(NetSdk.CLIENT_FindNextRecord(stuFindNextInParam, stuFindNextOutParam, 5000) ) {
					NetSDKTools.GetPointerDataToStructArr(stuFindNextOutParam.pRecordList, pstRecord);
	
					for(int i=0; i < stuFindNextOutParam.nRetRecordNum; i++) {
						nFindCount = i + count * nRecordCount;				
						
						System.out.println("[" + nFindCount + "]卡号:" + new String(pstRecord[i].szCardNo).trim());
						System.out.println("[" + nFindCount + "]用户ID:" + new String(pstRecord[i].szUserID).trim());
						System.out.println("[" + nFindCount + "]开始时间:" + pstRecord[i].stuValidStartTime.toStringTime());
						System.out.println("[" + nFindCount + "]结束时间:" + pstRecord[i].stuValidEndTime.toStringTime());
					}							
					
					if (stuFindNextOutParam.nRetRecordNum < nRecordCount)
					{
						break;
					} else {
						count ++;
					}
				} else {
					break;
				}
			}
			System.out.println("查询到的总数 : " + (nFindCount + 1));
			NetSdk.CLIENT_FindRecordClose(new NativeLong(stuFindOutParam.lFindeHandle));
		} else {
			System.err.println("Can Not Find This Record" + String.format("0x%x", NetSdk.CLIENT_GetLastError()));
		}
	}
	
	
	/// 准确查询门禁用户信息
	public void findSingleAccess() {
		NetSDKLib.FIND_RECORD_ACCESSCTLCARD_CONDITION stuAccessCondition = new NetSDKLib.FIND_RECORD_ACCESSCTLCARD_CONDITION();	
		stuAccessCondition.abCardNo = 1; //卡号查询条件是否有效
		String cardNo = "111";
		System.arraycopy(cardNo.getBytes(), 0, stuAccessCondition.szCardNo, 0, cardNo.getBytes().length);
		
		NetSDKLib.NET_IN_FIND_RECORD_PARAM stuFindInParam = new NetSDKLib.NET_IN_FIND_RECORD_PARAM();
		stuFindInParam.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; 
		stuFindInParam.pQueryCondition = stuAccessCondition.getPointer();
		
		NetSDKLib.NET_OUT_FIND_RECORD_PARAM stuFindOutParam = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM();

		stuAccessCondition.write();
		if(NetSdk.CLIENT_FindRecord(m_hLoginHandle, stuFindInParam, stuFindOutParam, 5000)) {
			stuAccessCondition.read();
			System.out.println("FindRecord Succeed" + "\n" + "FindHandle :" + stuFindOutParam.lFindeHandle);
			
			int nRecordCount = 10;
			NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM stuFindNextInParam = new NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM();
			stuFindNextInParam.lFindeHandle = stuFindOutParam.lFindeHandle;
			stuFindNextInParam.nFileCount = nRecordCount;  //想查询的记录条数
			
			NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARD pstRecord = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARD();
			
			NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM stuFindNextOutParam = new NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM();
			stuFindNextOutParam.nMaxRecordNum = nRecordCount;
			stuFindNextOutParam.pRecordList = pstRecord.getPointer();

			pstRecord.write();
			boolean zRet = NetSdk.CLIENT_FindNextRecord(stuFindNextInParam, stuFindNextOutParam, 5000);
			pstRecord.read();
			
			if(zRet) {		
				System.out.println("用户ID:" + new String(pstRecord.szUserID).trim());
				System.out.println("开始时间:" + pstRecord.stuValidStartTime.toStringTime());
				System.out.println("结束时间:" + pstRecord.stuValidEndTime.toStringTime());			
			} 
			
			NetSdk.CLIENT_FindRecordClose(new NativeLong(stuFindOutParam.lFindeHandle));
		} else {
			System.err.println("Can Not Find This Record" + String.format("0x%x", NetSdk.CLIENT_GetLastError()));
		}
	}
		
	
	/**
	 * 订阅视频统计摘要信息(人流量)
	 * @return
	 */
	public void startAttachVideoStatSummary() {
		
		NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM inParam = new NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
		inParam.nChannel = 0; // 通道0
		inParam.cbVideoStatSum = mVideoStatSumCB;
		
		NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM outParam = new NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
		
		m_hAttachHandle = NetSdk.CLIENT_AttachVideoStatSummary(m_hLoginHandle, inParam, outParam, 5000);
		if (m_hAttachHandle.longValue() == 0 ) {
			System.err.printf("Attach Video State Failed! LastError = 0x%x\n", NetSdk.CLIENT_GetLastError() );
		}
		else {
			System.out.println("Attach Video State Success. ");
		}
	}
	
	/**
	 * 取消订阅视频统计摘要信息
	 * @return
	 */
	public boolean stopAttachVideoStatSummary() {
		if (0 != m_hAttachHandle.longValue()) {
            NetSdk.CLIENT_DetachVideoStatSummary(m_hAttachHandle);
            System.out.println("Stop detach Video State event");
            m_hAttachHandle.setValue(0);
            return true;
		}
		
		return false;
	}
	
	/**
	 * 视频统计摘要信息回调函数原形
	 */
	public fVideoStatSumCB mVideoStatSumCB = new fVideoStatSumCB();
	public class fVideoStatSumCB implements NetSDKLib.fVideoStatSumCallBack{
	  	public void invoke(NativeLong lAttachHandle, NetSDKLib.NET_VIDEOSTAT_SUMMARY stVideoState, int dwBufLen, NativeLong dwUser){
	  		System.out.printf("Channel[%d] GetTime[%s]\n" +
	  				"People In  Information[Total[%d] Hour[%d] Today[%d]]\n" +
	  				"People Out Information[Total[%d] Hour[%d] Today[%d]]\n", 
	  				stVideoState.nChannelID , stVideoState.stuTime.toStringTime() , 
	  				stVideoState.stuEnteredSubtotal.nToday , 
	  				stVideoState.stuEnteredSubtotal.nHour , 
	  				stVideoState.stuEnteredSubtotal.nTotal , 
	  				stVideoState.stuExitedSubtotal.nToday , 
	  				stVideoState.stuExitedSubtotal.nHour , 
	  				stVideoState.stuExitedSubtotal.nTotal );
		}
	}
	
	/**
	 * 查询视频统计信息（人流量）
	 */
	public void findNumberState() {
		NetSDKLib.NET_IN_FINDNUMBERSTAT inParam = new NetSDKLib.NET_IN_FINDNUMBERSTAT();
		inParam.nChannelID = 0; // 通道号
		
		inParam.stStartTime.dwYear = 2016;// 开始时间
		inParam.stStartTime.dwMonth = 6;
		inParam.stStartTime.dwDay = 20;
		inParam.stStartTime.dwHour = 0;

		inParam.stEndTime.dwYear = 2016;// 结束时间
		inParam.stEndTime.dwMonth = 6;
		inParam.stEndTime.dwDay = 21;
		inParam.stEndTime.dwHour = 23;
					
		inParam.nGranularityType = 1;// 颗粒度				
		inParam.nWaittime = 5000; // 接口超时时间5s
		
		NetSDKLib.NET_OUT_FINDNUMBERSTAT outParam = new NetSDKLib.NET_OUT_FINDNUMBERSTAT();
		
		/// 获取查询句柄
		m_hFindHandle = NetSdk.CLIENT_StartFindNumberStat(m_hLoginHandle, inParam, outParam);
		if (m_hFindHandle.longValue() == 0) {
			System.err.printf("StartFindNumberStat Failed! LastError = 0x%x\n", NetSdk.CLIENT_GetLastError() );
		}
		
		System.out.println("dwTotalCount: " + outParam.dwTotalCount);			
		/// 查询
		NetSDKLib.NET_IN_DOFINDNUMBERSTAT inDoFind = new NetSDKLib.NET_IN_DOFINDNUMBERSTAT();
		inDoFind.nBeginNumber = 0; // 从0开始查询
		inDoFind.nCount = 10; // 每次查询10条
		inDoFind.nWaittime = 5000; //接口超时时间 5s
		
		NetSDKLib.NET_OUT_DOFINDNUMBERSTAT outDofind = new NetSDKLib.NET_OUT_DOFINDNUMBERSTAT();
		NetSDKLib.NET_NUMBERSTAT[] numberstat = (NetSDKLib.NET_NUMBERSTAT[])new NetSDKLib.NET_NUMBERSTAT().toArray(inDoFind.nCount);
		outDofind.nBufferLen = inDoFind.nCount * numberstat[0].dwSize;
		outDofind.pstuNumberStat = new Memory(outDofind.nBufferLen);
		outDofind.pstuNumberStat.clear(outDofind.nBufferLen);
		// Note： 初始化内存中 dwSize 字段的值，否则查询的结果为空
		NetSDKTools.SetStructArrToPointerData(numberstat, outDofind.pstuNumberStat);
		
		int bFound = 0;
		int index = 1;
		do {
			bFound = NetSdk.CLIENT_DoFindNumberStat(m_hFindHandle, inDoFind, outDofind);
			if (0 == bFound) {
				System.err.printf("DoFindNumberStat Failed! LastError = 0x%x\n", NetSdk.CLIENT_GetLastError() );
				break;
			}
			
			// 查询结果
			NetSDKTools.GetPointerDataToStructArr(outDofind.pstuNumberStat, numberstat);
			for(int i = 0; i < outDofind.nCount; i++, index ++) {
				System.out.println("index = " + index +
						" Start Time: " + numberstat[i].stuStartTime.toStringTime() +
						" Stop Time: " + numberstat[i].stuEndTime.toStringTime() +
						" Enter Total: " + numberstat[i].nEnteredSubTotal +
						" Exit Total: " + numberstat[i].nExitedSubtotal + "\n"
						);
			}
			
			// 查询下一次
			inDoFind.nBeginNumber += inDoFind.nCount; // 从上一次结束地方开始查询
		}while(outDofind.nCount >= inDoFind.nCount);
		
		NetSdk.CLIENT_StopFindNumberStat(m_hFindHandle);
	}
	
	// 车流量
    public void flowstateIVSEvent() { 
		int bNeedPicture = 0; // 是否需要图片
		int ChannelId = 0; // 0 通道 

        NativeLong m_hAttachHandle =  NetSdk.CLIENT_RealLoadPictureEx(m_hLoginHandle, ChannelId,  NetSDKLib.EVENT_IVS_ALL , bNeedPicture , m_AnalyzerDataCB , null , null);
        if( m_hAttachHandle.longValue() != 0  )
        {
            System.out.println("CLIENT_RealLoadPictureEx Success\n");
        }
        else
        {
            System.err.printf("CLIENT_RealLoadPictureEx Failed!LastError = %x\n", NetSdk.CLIENT_GetLastError() );
            return;
        }
    }
	
    private fAnalyzerDataCB m_AnalyzerDataCB = new fAnalyzerDataCB();
    
    /* 智能报警事件回调 */
    public class fAnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack {
		@Override
		public int invoke(NativeLong lAnalyzerHandle, int dwAlarmType,
				Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,
				Pointer dwUser, int nSequence, Pointer reserved) {
        	if(pAlarmInfo == null) {
        		return 0;
        	}
			switch(dwAlarmType)
            {
                case NetSDKLib.EVENT_IVS_TRAFFIC_FLOWSTATE: ///< 交通流量统计事件
                {
                	NetSDKLib.DEV_EVENT_TRAFFIC_FLOW_STATE flowstate = new NetSDKLib.DEV_EVENT_TRAFFIC_FLOW_STATE();
                    NetSDKTools.GetPointerData(pAlarmInfo, flowstate);
                    
					for(int i =0 ; i< flowstate.nStateNum ; i++)
		            {
		                System.out.printf("Lane[%d] Flow[%d] Period[%d]\n" , 
		                		flowstate.stuStates[i].nLane , 
		                		flowstate.stuStates[i].dwFlow , 
		                		flowstate.stuStates[i].dwPeriod );
		            }
					System.out.printf("\n");                
                    break;
                }
                case NetSDKLib.EVENT_IVS_TRAFFICGATE:  ///< 交通卡口事件
                {
                	NetSDKLib.DEV_EVENT_TRAFFICGATE_INFO trafficgate = new NetSDKLib.DEV_EVENT_TRAFFICGATE_INFO();
                	NetSDKTools.GetPointerData(pAlarmInfo, trafficgate);
                	
                	System.out.println("事件名称 ：" + new String(trafficgate.szName).trim());
                	System.out.println("Time : " + trafficgate.UTC);
                	break;
                }
                default:
                	break;
                
            }	
			
			//pBuffer收到的图片数据
			File currentPath = new File(".");
			String strFileName = currentPath.getAbsoluteFile().getParent() + "\\" + System.currentTimeMillis() + ".jpg"; 
			//保存图片到本地文件
			NetSDKTools.savePicture(pBuffer , dwBufSize , strFileName); 
			System.out.println("strFileName : " + strFileName);
			return 0;
		} 	
    }
	
	public void RunTest()
	{
		System.out.println("Run Test");		
		MenuEx menu = new MenuEx();
		menu.AddItem(new MenuItemEx(this , "flowstateIVSEvent" , "flowstateIVSEvent"));  	// 车流量
		menu.AddItem(new MenuItemEx(this , "findNumberState" , "findNumberState"));   // 查询视频统计信息（人流量）
		menu.AddItem(new MenuItemEx(this , "startAttachVideoStatSummary" , "startAttachVideoStatSummary")); // 订阅视频统计摘要信息(人流量)
		menu.Run();
	}

	public static void main(String[]args)
	{
		JNADemo demo = new JNADemo();
		demo.InitTest();
		demo.RunTest();
		demo.EndTest();
	}
}

